package extendsdemo


/**
  * 抽象类，需要在类上加上abstract
  * 抽象方法不需要abstract修饰，只需要声明下（不带内容）
  */
abstract class Element {
  def contents: Array[String]

  /**
    * 当不需要参数时，声明和调用时都可以不带空括号
    *
    * @return
    */
  def height: Int = contents.length

  def width: Int = if (height == 0) 0 else contents(0).length
}

/**
  * 定义工厂方法和私有类
  */
object Element {

  private class ArrayElement(conts: Array[String]) extends Element {
    /**
      * 可以用字段或者方法实现父类的非Unit抽象方法
      */
    val contents: Array[String] = conts
  }

  /**
    * 在主构造方法中调用父类构造方法
    *
    * @param s
    */
  private class LineElement(s: String) extends ArrayElement(Array(s)) {

    /**
      * 重写父类方法 要加override 修饰
      *
      * @return
      */
    override def height: Int = 1

    override def width: Int = s.length
  }

  //工厂方法
  def elem(conts: Array[String]): Element =
    new ArrayElement(conts)

  def elem(s: String): Element =
    new LineElement(s)
}
